package com.tanhua.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.api.UserInfoApi;
import com.tanhua.api.VideoApi;
import com.tanhua.app.exception.BusinessException;
import com.tanhua.app.intercept.UserHolder;
import com.tanhua.commons.utils.Constants;
import com.tanhua.config.template.OssTemplate;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VideoVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class SmallVideosService {
    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FdfsWebServer webServer;

    @DubboReference
    private VideoApi videoApi;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private FastFileStorageClient client;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     *发布视频
     * @param videoThumbnail:封面图
     * @param videoFile:视频文件
     */
    public void saveVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //1.判断发布内容是否存在
        if (videoThumbnail.isEmpty() || videoFile.isEmpty()){
            throw new BusinessException(ErrorResult.videoNullError());
        }
        //2.存在，将视频发布到FastDFS,获取访问视频的路径URL
        //获取发布视频的文件名称 abc.mp4
        String filename = videoFile.getOriginalFilename();
        //2.获取文件的后缀 mp4
        final String fileName = filename.substring(filename.lastIndexOf(".") + 1);
        //3.上传文件
        final StorePath storePath = client.uploadFile(videoFile.getInputStream(),
                videoFile.getSize(), fileName, null);
        //4.拼接访问路径
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();

        //5.将封面图上传到阿里云,获取访问路径
        String imageUrl = ossTemplate.upload(videoThumbnail.getInputStream(), videoThumbnail.getOriginalFilename());

        //6.构造对象，储存到数据库
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(imageUrl);
        video.setVideoUrl(videoUrl);
        video.setText("我就是我，不一样的烟火");//此处被写死，后面应该是将发布的文字能容作为参数传递过来

        //7.调用Api进行保存
        String videoId = videoApi.saveVideo(video);
        if (StringUtils.isEmpty(videoId)){
            //发布失败
            throw new BusinessException(ErrorResult.videoError());
        }
    }

    /**
     * 查询小视频列表（分页查询，先查推荐视频）
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult queryVideoList(Integer page, Integer pagesize) {
        //1、查询redis数据
        String key = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String redisVideo = redisTemplate.opsForValue().get(key);

        //2、判断redis数据是否存在，判断redis中数据是否满足本次分页条数
        List<Video> videoList = new ArrayList<>();
        int redisPage = 0;//redis中数据的总页数
        if (StringUtils.isNoneEmpty(redisVideo)){
            //3、如果redis数据存在，根据VID查询数据
            String[] videos = redisVideo.split(",");
            //4.判断当前页的起始条数是否小于数组总数
            if ((page-1)*pagesize < videos.length){
                List<Long> vidList = Arrays.stream(videos).skip((page - 1) * pagesize).limit(pagesize)
                        .map(vid -> Long.valueOf(vid))
                        .collect(Collectors.toList());

                //5、调用API根据VID数组查询动态数据
                videoList = videoApi.findByVids(vidList);
            }
            //计算redis中数据的总页数
            redisPage = PageUtil.totalPage(videos.length, pagesize);
        }

        //6.当前查询的页数，大于redis中的缓存总数时
        if (page>redisPage){
            videoList = videoApi.findByPage((page-redisPage),pagesize);
        }

        //7.获的小视频列表用户的详情
        //获取用户的ids
        List<Long> ids = videoList.stream().map(Video::getUserId).collect(Collectors.toList());
        //查询用户的详情，根据id
        List<UserInfo> userInfoList = userInfoApi.findByUserIds(ids, null);
        //转换成map集合
        Map<Long, UserInfo> map = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, Function.identity()));

        //8.封装vo对象
        List<VideoVo> videoVos = new ArrayList<>();
        for (Video video : videoList) {
            UserInfo userInfo = map.get(video.getUserId());
            if (userInfo != null){
                VideoVo videoVo = VideoVo.init(userInfo, video);
                videoVos.add(videoVo);
            }
        }

        return new PageResult(page,pagesize,0,videoVos);
    }
}
